package ar.edu.itba.it.paw.repo.impl;


import java.util.Iterator;
import java.util.List;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import ar.edu.itba.it.paw.domain.Auction;
import ar.edu.itba.it.paw.domain.Category;
import ar.edu.itba.it.paw.domain.OrderProducts;
import ar.edu.itba.it.paw.domain.Product;
import ar.edu.itba.it.paw.domain.Question;
import ar.edu.itba.it.paw.domain.User;
import ar.edu.itba.it.paw.repo.AbstractHibernateRepo;
import ar.edu.itba.it.paw.repo.ProductRepo;

@Repository
public class HibernateProductRepo extends AbstractHibernateRepo implements ProductRepo{

	@Autowired
	public HibernateProductRepo(SessionFactory sessionFactory){
		super(sessionFactory);
	}

	@Override
	public List<Product> getAllProducts(OrderProducts order) {
		String type = "";
		if(!order.isAscending()){
			type = "desc";
		}
		String query;
		if(order.getValue().equals("name")){
			/*Si es nombre lo paso a minuscula*/
			query = "from Product where quantity > 0 order by Lower(" + order.getValue() + " ) " + type ;
		}else {
			/*VER si hace falta hacer los join o los hace hibernate*/
			query = "from Product where quantity > 0 order by " + order.getValue() + " " + type ;
		}
		List<Product> list = null;
		try{
		list = find(query);
		}catch(Exception e){
			e.printStackTrace();
		}
		/*Esto se podria meter en el hql seteando en FALSE el campo ended de todos los productos*/
		Iterator<Product> it = list.iterator();
		while(it.hasNext()){
			Product prod = it.next();
			if(prod.getClass() == Auction.class){
				if(((Auction)prod).isEnded()){
					it.remove();
				}
			}
		}
		if(order.getAmount() != 0){
			int removes = list.size() - order.getAmount();
			for(int i = 0 ; i < removes ; ++i){
				list.remove(order.getAmount());
			}
		}
		return list;
	}
	
	@Override
	public List<Product> getAllProducts(OrderProducts order, Category category) {
		List<Product> prod_list = getAllProducts(order);
		Iterator<Product> it = prod_list.iterator();
		while(it.hasNext()){
			Product prod = it.next();
			if(!prod.getCategory().equals(category)){
				it.remove();
			}
		}
		return prod_list;
	}

	@Override
	public Product getProduct(int id) {
		return get(Product.class, id);
	}

	
	@Override
	public List<Product> getProductsByCategory(Category category) {

		List<Product> list = null;
		list = find("from Product as p where p.category = ?", category);
		Iterator<Product> it = list.iterator();
		while(it.hasNext()){
			Product prod = it.next();
			if(prod.getClass() == Auction.class){
				if(((Auction)prod).isEnded()){
					it.remove();
				}
			}
		}
		return list;
	}

	@Override
	public List<Product> getVisitedProducts(int quantity) {
		/*VER para que esta el quantity en la clase OrderProducts*/
		List<Product>  list = this.getAllProducts(new OrderProducts("visits",false,quantity));
		int list_quant = list.size();
		if(list_quant >= quantity)
			return list.subList(0, quantity);
		else
			return list;
	}

	@Override
	public void addProduct(Product product) {
		try{
			save(product);
		}catch(Exception e){
			e.printStackTrace();
		}
	}

	@Override
	public void deleteProduct(Product product) {
		//Product to_delete = get(Product.class, product.getId());
		//delete(to_delete);
		delete(product);
	}

	@Override
	public List<Product> getAllProducts() {
		return this.getAllProducts(new OrderProducts("name"));
	}

	@Override
	public List<Product> getOtherUserProducts(User user) {
		if(user == null)
			throw new IllegalArgumentException();
		List<Product> product_list = this.getAllProducts();
		Iterator<Product> product_iterator = product_list.iterator();
		while(product_iterator.hasNext()){
			Product prod = product_iterator.next();
			if(prod.getOwner().equals(user)){
				product_iterator.remove();
			}
		}
		return product_list;
	}


//	@Override
//	public List<Question> getQuestions(Product product) {
//		if(product == null){
//			throw new IllegalArgumentException("Producto nulo");
//		}
//		try{
//			return find("from Question as q where q.product.id = ?",product.getId());
//		}catch(Exception e){
//			e.printStackTrace();
//		}
//		return null;
//	}
	
//	@Override
//	public List<Question> getQuestions(User user) {
//		if(user == null){
//			throw new IllegalArgumentException("Producto nulo");
//		}
//		try{
//			return find("from Question as q where q.product.owner.id = ?",user.getId());
//		}catch(Exception e){
//			e.printStackTrace();
//		}
//		return null;
//	}
	
	public Question getQuestion(int id){
		return get(Question.class, id);
	}
	
//	public void addQuestion(Question question){
//		if(question == null){
//			throw new IllegalArgumentException();
//		}
//		try{
//			save(question);	
//		}catch(Exception e){
//			e.printStackTrace();
//		}
//		
//	}
	
//	public void addOffer(Offer offer){
//		if(offer == null){
//			throw new IllegalArgumentException();
//		}
//		save(offer);
//	}
	
//	public List<Product> getBoughtProducts(User user){
//		return find("select distinct t.product from Transaction t where t.buyer.id = ?", user.getId());
//	}
//	
//	public List<Product> getSoldProducts(User user){
//		return find("select distinct t.product from Transaction t where t.seller.id = ?", user.getId());
//	}
}
